﻿#include "GUIRadiossResultRequestDialog.h"
#include "ui_GUIRadiossResultRequestDialog.h"

#include "FITK_Kernel/FITKCore/FITKActionOperator.h"
#include "FITK_Kernel/FITKAppFramework/FITKAppFramework.h"
#include "FITK_Kernel/FITKAppFramework/FITKAppSettings.h"
#include "FITK_Kernel/FITKAppFramework/FITKGlobalData.h"
#include "FITK_Component/FITKRadiossData/FITKRadiossCase.h"
#include "FITK_Component/FITKRadiossData/FITKRadiossResultRequest.h"

#include "GUITimeHistoryACCELDialog.h"

#include <QLineEdit>
#include <QLabel>
#include <QCheckBox>
#include <QComboBox>
#include <QDebug>

namespace GUI
{
    GUIRadiossResultRequestDialog::GUIRadiossResultRequestDialog(Core::FITKActionOperator* oper, QWidget *parent) :
        GUIDialogBase(parent),
        _oper(oper),
        _ui(new Ui::GUIRadiossResultRequestDialog)
    {
        _ui->setupUi(this);
        // 设置对话框关闭时自动删除
        setAttribute(Qt::WA_DeleteOnClose);
        //去掉问号
        Qt::WindowFlags flags = windowFlags();
        flags &= ~Qt::WindowContextHelpButtonHint;
        setWindowFlags(flags);
        Radioss::FITKRadiossCase* caseData = FITKAPP->getGlobalData()->getPhysicsData<Radioss::FITKRadiossCase>();
        if (caseData)
            _resultRequest = caseData->getResultRequest();
        //初始化
        this->init();
        //设置窗口自适应隐藏组件
        this->layout()->setSizeConstraint(QLayout::SetMinAndMaxSize);
    }

    GUIRadiossResultRequestDialog::~GUIRadiossResultRequestDialog()
    {
        if (_ui) {
            delete _ui;
            _ui = nullptr;
        }
    }

    void GUIRadiossResultRequestDialog::on_pushButton_Cancel_clicked()
    {
        this->reject();
    }

    void GUIRadiossResultRequestDialog::on_pushButton_OK_clicked()
    {
        this->setResultRequestParams();
        this->accept();
    }

    void GUIRadiossResultRequestDialog::pushButton_ACCEL_clicked()
    {
        GUITimeHistoryACCELDialog* dialog = new GUITimeHistoryACCELDialog(_oper, this);
        dialog->show();

    }
    void GUIRadiossResultRequestDialog::pushButton_INTER_clicked()
    {
        qDebug() << 3;

    }
    void GUIRadiossResultRequestDialog::pushButton_RWALL_clicked()
    {
        qDebug() << 4;

    }
    void GUIRadiossResultRequestDialog::pushButton_RBODY_clicked()
    {
        qDebug() << 1;

    }
    void GUIRadiossResultRequestDialog::pushButton_SECTIO_clicked()
    {
        qDebug() <<5;
    }
    void GUIRadiossResultRequestDialog::init()
    {
        if (!_resultRequest) return;

        this->initAnimationParamsTreeNode();
        this->initNodalOutputAnimationsTreeNode();
        this->initElementalOutputAnimationsTreeNode();
        this->initTimeHistoryTreeNode();

        _ui->treeWidget->header()->setSectionResizeMode(QHeaderView::ResizeToContents);
        _ui->treeWidget->expandAll();
    }
  
    void GUIRadiossResultRequestDialog::initAnimationParamsTreeNode()
    {
        if (!_resultRequest) return;

        ChildTreeNodeData childItemData;
        QTreeWidgetItem* basicParamsRoot = this->addTopLevelItem(QObject::tr(" Animation File Parameters"));
        // 时间
        childItemData.setText(QObject::tr("Start time"));
        childItemData.setEnableCheckBox(false);
        childItemData.setEnableLineEdit(true, "StartTime_Edit", QString::number(_resultRequest->getStartTime()), "s");
        this->addChildItem(basicParamsRoot, childItemData);
        // 频率
        childItemData.setText(QObject::tr("Frequency"));
        childItemData.setEnableCheckBox(false);
        childItemData.setEnableLineEdit(true, "Frequency_Edit", QString::number(_resultRequest->getFrequency()), "");
        this->addChildItem(basicParamsRoot, childItemData);
    }

    void GUIRadiossResultRequestDialog::initNodalOutputAnimationsTreeNode()
    {
        if (!_resultRequest) return;
        QList<Radioss::FITKRadiossResultRequest::NodalOutputAnimationsType> nodalAnims = _resultRequest->getNodalOutputAnim();

        ChildTreeNodeData childItemData;
        QTreeWidgetItem* nodalAnimRoot = this->addTopLevelItem(QObject::tr("Nodal Output Animations"));
        // 位移
        childItemData.setText(QObject::tr("Displacement"));
        childItemData.setEnableCheckBox(true, "Nodal_Displacement_CheckBox",
            nodalAnims.contains(Radioss::FITKRadiossResultRequest::Nodal_Displacement));
        this->addChildItem(nodalAnimRoot, childItemData);
        // 速度
        childItemData.setText(QObject::tr("Velocity"));
        childItemData.setEnableCheckBox(true, "Nodal_Velocity_CheckBox",
            nodalAnims.contains(Radioss::FITKRadiossResultRequest::Nodal_Velocity));
        this->addChildItem(nodalAnimRoot, childItemData);
        // 加速度
        childItemData.setText(QObject::tr("Acceleration"));
        childItemData.setEnableCheckBox(true, "Nodal_Acceleration_CheckBox",
            nodalAnims.contains(Radioss::FITKRadiossResultRequest::Nodal_Acceleration));
        this->addChildItem(nodalAnimRoot, childItemData);
        // 加速度
        childItemData.setText(QObject::tr("Contact forces"));
        childItemData.setEnableCheckBox(true, "Nodal_ContactForces_CheckBox",
            nodalAnims.contains(Radioss::FITKRadiossResultRequest::Nodal_ContactForces));
        this->addChildItem(nodalAnimRoot, childItemData);
        // 刚体的力和力矩
        childItemData.setText(QObject::tr("Rigid body forces and moments"));
        childItemData.setEnableCheckBox(true, "Nodal_RigidBodyForcesMoments_CheckBox",
            nodalAnims.contains(Radioss::FITKRadiossResultRequest::Nodal_RigidBodyForcesMoments));
        this->addChildItem(nodalAnimRoot, childItemData);
        // 内部力
        childItemData.setText(QObject::tr("Internal forces"));
        childItemData.setEnableCheckBox(true, "Nodal_InternalForces_CheckBox",
            nodalAnims.contains(Radioss::FITKRadiossResultRequest::Nodal_InternalForces));
        this->addChildItem(nodalAnimRoot, childItemData);
        // 接触压力
        childItemData.setText(QObject::tr("Contact pressure"));
        childItemData.setEnableCheckBox(true, "Nodal_ContactPressure_CheckBox",
            nodalAnims.contains(Radioss::FITKRadiossResultRequest::Nodal_ContactPressure));
        this->addChildItem(nodalAnimRoot, childItemData);
    }

    void GUIRadiossResultRequestDialog::initElementalOutputAnimationsTreeNode()
    {
        if (!_resultRequest) return;
        QList<Radioss::FITKRadiossResultRequest::ElementalOutputAnimationsType> elementalAnims = _resultRequest->getElementalOutputAnim();

        ChildTreeNodeData childItemData;
        QTreeWidgetItem* elementalAnimRoot = this->addTopLevelItem(QObject::tr("Elemental Output Animations"));
        // 应力
        childItemData.setText(QObject::tr("Stress"));
        childItemData.setEnableCheckBox(true, "Elemental_Stress_CheckBox",
            elementalAnims.contains(Radioss::FITKRadiossResultRequest::Elemental_Stress));
        this->addChildItem(elementalAnimRoot, childItemData);
        // 所有积分点的应力
        childItemData.setText(QObject::tr("Stress for all integration points"));
        childItemData.setEnableCheckBox(true, "Elemental_StressAllIntegrationPoints_CheckBox",
            elementalAnims.contains(Radioss::FITKRadiossResultRequest::Elemental_StressAllIntegrationPoints));
        this->addChildItem(elementalAnimRoot, childItemData);
        // 应变
        childItemData.setText(QObject::tr("Strain"));
        childItemData.setEnableCheckBox(true, "Elemental_Strain_CheckBox",
            elementalAnims.contains(Radioss::FITKRadiossResultRequest::Elemental_Strain));
        this->addChildItem(elementalAnimRoot, childItemData);
        // 所有积分点的应变
        childItemData.setText(QObject::tr("Strain for all integration points"));
        childItemData.setEnableCheckBox(true, "Elemental_StrainAllIntegrationPoints_CheckBox",
            elementalAnims.contains(Radioss::FITKRadiossResultRequest::Elemental_StrainAllIntegrationPoints));
        this->addChildItem(elementalAnimRoot, childItemData);
        // 特殊能量密度 （包含砖块元素数据）六面体
        childItemData.setText(QObject::tr("Specific energy density"));
        childItemData.setEnableCheckBox(true, "Elemental_SpecificEnergyDensity_CheckBox",
            elementalAnims.contains(Radioss::FITKRadiossResultRequest::Elemental_SpecificEnergyDensity));
        this->addChildItem(elementalAnimRoot, childItemData);
        // 塑性应变 （包含砖块元素数据）六面体
        childItemData.setText(QObject::tr("Plastic strain"));
        childItemData.setEnableCheckBox(true, "Elemental_PlasticStrain_CheckBox",
            elementalAnims.contains(Radioss::FITKRadiossResultRequest::Elemental_PlasticStrain));
        this->addChildItem(elementalAnimRoot, childItemData);
        // 沙漏能量 (发动机舱)
        childItemData.setText(QObject::tr("Hourglass energy"));
        childItemData.setEnableCheckBox(true, "Elemental_HourglassEnergy_CheckBox",
            elementalAnims.contains(Radioss::FITKRadiossResultRequest::Elemental_HourglassEnergy));
        this->addChildItem(elementalAnimRoot, childItemData);
        // 等效应力
        childItemData.setText(QObject::tr("Von mises stress"));
        childItemData.setEnableCheckBox(true, "Elemental_VonMisesStress_CheckBox",
            elementalAnims.contains(Radioss::FITKRadiossResultRequest::Elemental_VonMisesStress));
        this->addChildItem(elementalAnimRoot, childItemData);
        // 压力
        childItemData.setText(QObject::tr("Pressure"));
        childItemData.setEnableCheckBox(true, "Elemental_Pressure_CheckBox",
            elementalAnims.contains(Radioss::FITKRadiossResultRequest::Elemental_Pressure));
        this->addChildItem(elementalAnimRoot, childItemData);
        // 密度
        childItemData.setText(QObject::tr("Density"));
        childItemData.setEnableCheckBox(true, "Elemental_Density_CheckBox",
            elementalAnims.contains(Radioss::FITKRadiossResultRequest::Elemental_Density));
        this->addChildItem(elementalAnimRoot, childItemData);
        // 壳的损伤
        childItemData.setText(QObject::tr("Shell damage of all"));
        childItemData.setEnableCheckBox(true, "Elemental_ShellDamageOfAll_CheckBox",
            elementalAnims.contains(Radioss::FITKRadiossResultRequest::Elemental_ShellDamageOfAll));
        this->addChildItem(elementalAnimRoot, childItemData);
        // 实体的损伤
        childItemData.setText(QObject::tr("Solid damage of all"));
        childItemData.setEnableCheckBox(true, "Elemental_SolidDamageOfAll_CheckBox",
            elementalAnims.contains(Radioss::FITKRadiossResultRequest::Elemental_SolidDamageOfAll));
        this->addChildItem(elementalAnimRoot, childItemData);
    }

    void GUIRadiossResultRequestDialog::initTimeHistoryTreeNode()
    {
        ChildTreeNodeData childItemData;
        QTreeWidgetItem* timeHistoryRoot = this->addTopLevelItem(QObject::tr("Time History"));
        //ACCEL
        childItemData.setText(QObject::tr("ACCEL"));
        childItemData.setEnableCheckBox(true);
        childItemData.setEnablePushButton(true, "pushButton_ACCEL", "Edit-ACCEL");
        this->addChildItem(timeHistoryRoot, childItemData);
        //INTER
        childItemData.setText(QObject::tr("INTER"));
        childItemData.setEnableCheckBox(true);
        childItemData.setEnablePushButton(true, "pushButton_INTER", "Edit-INTER");
        this->addChildItem(timeHistoryRoot, childItemData);
        //RWALL
        childItemData.setText(QObject::tr("RWALL"));
        childItemData.setEnableCheckBox(true);
        childItemData.setEnablePushButton(true, "pushButton_RWALL", "Edit-RWALL");
        this->addChildItem(timeHistoryRoot, childItemData);
        //RBODY
        childItemData.setText(QObject::tr("RBODY"));
        childItemData.setEnableCheckBox(true);
        childItemData.setEnablePushButton(true, "pushButton_RBODY", "Edit-RBODY");
        this->addChildItem(timeHistoryRoot, childItemData);
        //SECTIO
        childItemData.setText(QObject::tr("SECTIO"));
        childItemData.setEnableCheckBox(true);
        childItemData.setEnablePushButton(true, "pushButton_SECTIO", "Edit-SECTIO");
        this->addChildItem(timeHistoryRoot, childItemData);



    }

    void GUIRadiossResultRequestDialog::setResultRequestParams()
    {
        if (!_resultRequest) return;

        // 设置时间，频率
        _resultRequest->setStartTime(getLineEditValue("StartTime_Edit"));
        _resultRequest->setFrequency(getLineEditValue("Frequency_Edit"));

        // 设置节点动画输出
        QList<Radioss::FITKRadiossResultRequest::NodalOutputAnimationsType> nodalAnims;
        if (getCheckBoxState("Nodal_Displacement_CheckBox"))
            nodalAnims.append(Radioss::FITKRadiossResultRequest::Nodal_Displacement);
        if (getCheckBoxState("Nodal_Velocity_CheckBox"))
            nodalAnims.append(Radioss::FITKRadiossResultRequest::Nodal_Velocity);
        if (getCheckBoxState("Nodal_Acceleration_CheckBox"))
            nodalAnims.append(Radioss::FITKRadiossResultRequest::Nodal_Acceleration);
        if (getCheckBoxState("Nodal_ContactForces_CheckBox"))
            nodalAnims.append(Radioss::FITKRadiossResultRequest::Nodal_ContactForces);
        if (getCheckBoxState("Nodal_RigidBodyForcesMoments_CheckBox"))
            nodalAnims.append(Radioss::FITKRadiossResultRequest::Nodal_RigidBodyForcesMoments);
        if (getCheckBoxState("Nodal_InternalForces_CheckBox"))
            nodalAnims.append(Radioss::FITKRadiossResultRequest::Nodal_InternalForces);
        if (getCheckBoxState("Nodal_ContactPressure_CheckBox"))
            nodalAnims.append(Radioss::FITKRadiossResultRequest::Nodal_ContactPressure);
        _resultRequest->setNodalOutputAnim(nodalAnims);

        // 设置单元动画输出
        QList<Radioss::FITKRadiossResultRequest::ElementalOutputAnimationsType> elementalAnims;
        if (getCheckBoxState("Elemental_Stress_CheckBox"))
            elementalAnims.append(Radioss::FITKRadiossResultRequest::Elemental_Stress);
        if (getCheckBoxState("Elemental_StressAllIntegrationPoints_CheckBox"))
            elementalAnims.append(Radioss::FITKRadiossResultRequest::Elemental_StressAllIntegrationPoints);
        if (getCheckBoxState("Elemental_Strain_CheckBox"))
            elementalAnims.append(Radioss::FITKRadiossResultRequest::Elemental_Strain);
        if (getCheckBoxState("Elemental_StrainAllIntegrationPoints_CheckBox"))
            elementalAnims.append(Radioss::FITKRadiossResultRequest::Elemental_StrainAllIntegrationPoints);
        if (getCheckBoxState("Elemental_SpecificEnergyDensity_CheckBox"))
            elementalAnims.append(Radioss::FITKRadiossResultRequest::Elemental_SpecificEnergyDensity);
        if (getCheckBoxState("Elemental_PlasticStrain_CheckBox"))
            elementalAnims.append(Radioss::FITKRadiossResultRequest::Elemental_PlasticStrain);
        if (getCheckBoxState("Elemental_HourglassEnergy_CheckBox"))
            elementalAnims.append(Radioss::FITKRadiossResultRequest::Elemental_HourglassEnergy);
        if (getCheckBoxState("Elemental_VonMisesStress_CheckBox"))
            elementalAnims.append(Radioss::FITKRadiossResultRequest::Elemental_VonMisesStress);
        if (getCheckBoxState("Elemental_Pressure_CheckBox"))
            elementalAnims.append(Radioss::FITKRadiossResultRequest::Elemental_Pressure);
        if (getCheckBoxState("Elemental_Density_CheckBox"))
            elementalAnims.append(Radioss::FITKRadiossResultRequest::Elemental_Density);
        if (getCheckBoxState("Elemental_ShellDamageOfAll_CheckBox"))
            elementalAnims.append(Radioss::FITKRadiossResultRequest::Elemental_ShellDamageOfAll);
        if (getCheckBoxState("Elemental_SolidDamageOfAll_CheckBox"))
            elementalAnims.append(Radioss::FITKRadiossResultRequest::Elemental_SolidDamageOfAll);
        _resultRequest->setElementalOutputAnim(elementalAnims);
    }

    QTreeWidgetItem * GUIRadiossResultRequestDialog::addTopLevelItem(const QString & text)
    {
        if (text.isEmpty()) return nullptr;
        QTreeWidgetItem* item = new QTreeWidgetItem();
        item->setText(0, text);
        _ui->treeWidget->addTopLevelItem(item);
        return item;
    }
    QTreeWidgetItem * GUIRadiossResultRequestDialog::addChildItem(QTreeWidgetItem * p, const ChildTreeNodeData & childItemData)
    {
        if (!p || childItemData._text.isEmpty()) return nullptr;
        //创建子节点数据
        QTreeWidgetItem* item = new QTreeWidgetItem(p);
        item->setText(0, childItemData._text);
        //创建窗口
        QWidget* widget = new QWidget(this);
        QHBoxLayout* layout = new QHBoxLayout();
        widget->setLayout(layout);
        //创建交互逻辑
        if (childItemData._isEnableCheckBox && !childItemData._isEnableLineEdit && !childItemData._isEnablePushButton)
        {
            QCheckBox* checkBox = new QCheckBox(this);
            checkBox->setObjectName(childItemData._checkBox_objectName);
            checkBox->setCheckState((childItemData._checkBox_Data ? Qt::CheckState::Checked : Qt::CheckState::Unchecked));
            QLabel* qlabel = new QLabel(this);
            qlabel->setText((childItemData._checkBox_Data ? "True" : "False"));
            layout->addWidget(checkBox);
            layout->addWidget(qlabel);
            layout->setStretch(1, 1);
            connect(checkBox, &QCheckBox::stateChanged, [=](int state) {
                if (state == Qt::CheckState::Checked)
                    qlabel->setText("True");
                else
                    qlabel->setText("False");
            });
        }
        else if (!childItemData._isEnableCheckBox && childItemData._isEnableLineEdit)
        {
            QLineEdit* lineEdit = new QLineEdit(this);
            lineEdit->setObjectName(childItemData._lineEdit_objectName);
            lineEdit->setText(childItemData._lineEdit_Data);
            QLabel* qlabel = new QLabel(this);
            qlabel->setText(childItemData._unit);
            layout->addWidget(lineEdit);
            layout->addWidget(qlabel);
            layout->setStretch(1, 1);
        }
        else if (childItemData._isEnableCheckBox && childItemData._isEnableLineEdit)
        {
            QCheckBox* checkBox = new QCheckBox(this);
            checkBox->setObjectName(childItemData._checkBox_objectName);
            checkBox->setCheckState((childItemData._checkBox_Data ? Qt::CheckState::Checked : Qt::CheckState::Unchecked));
            QLineEdit* lineEdit = new QLineEdit(this);
            lineEdit->setObjectName(childItemData._lineEdit_objectName);
            lineEdit->setText(childItemData._lineEdit_Data);
            QLabel* qlabel = new QLabel(this);
            qlabel->setText(childItemData._unit);
            lineEdit->setEnabled((childItemData._checkBox_Data ? true : false));
            layout->addWidget(checkBox);
            layout->addWidget(lineEdit);
            layout->addWidget(qlabel);
            layout->setStretch(2, 1);

            connect(checkBox, &QCheckBox::stateChanged, [=](int state) {
                if (state == Qt::CheckState::Checked)
                    lineEdit->setEnabled(true);
                else
                    lineEdit->setEnabled(false);
            });
        }
        else if (childItemData._isEnableComboBox && childItemData._comboBox_ItemDatas.size() == childItemData._comboBox_items.size())
        {
            QComboBox* comboBox = new QComboBox(this);
            comboBox->setObjectName(childItemData._comboBox_objectName);
            for (int i = 0; i < childItemData._comboBox_ItemDatas.size(); ++i)
            {
                comboBox->addItem(childItemData._comboBox_items[i], childItemData._comboBox_ItemDatas[i]);
            }
            layout->addWidget(comboBox);
            int index = comboBox->findData(childItemData._comboBox_Data);
            if(index < 0)
                comboBox->setCurrentIndex(0);
            else
                comboBox->setCurrentIndex(index);
        }
        else if (childItemData._isEnableCheckBox && !childItemData._isEnableLineEdit && childItemData._isEnablePushButton)
        {
            QCheckBox* checkBox = new QCheckBox(this);
            checkBox->setObjectName(childItemData._checkBox_objectName);
            checkBox->setCheckState(childItemData._checkBox_Data ? Qt::Checked : Qt::Unchecked);

            QPushButton* pushButton = new QPushButton(this);
            pushButton->setObjectName(childItemData._pushButton_objectName);
            pushButton->setText(childItemData._pushButton_Text);
            pushButton->setEnabled(childItemData._checkBox_Data);

            layout->addWidget(checkBox);
            layout->addWidget(pushButton);
            layout->setStretch(1, 1);

            connect(checkBox, &QCheckBox::stateChanged, [=](int state) {
                pushButton->setEnabled(state == Qt::Checked);
            });
            // 手动连接按钮点击信号
            if (pushButton->objectName() == "pushButton_ACCEL")
                connect(pushButton, &QPushButton::clicked, this, &GUIRadiossResultRequestDialog::pushButton_ACCEL_clicked);
            else if (pushButton->objectName() == "pushButton_INTER")
                connect(pushButton, &QPushButton::clicked, this, &GUIRadiossResultRequestDialog::pushButton_INTER_clicked);
            else if (pushButton->objectName() == "pushButton_RWALL")
                connect(pushButton, &QPushButton::clicked, this, &GUIRadiossResultRequestDialog::pushButton_RWALL_clicked);
            else if (pushButton->objectName() == "pushButton_RBODY")
                connect(pushButton, &QPushButton::clicked, this, &GUIRadiossResultRequestDialog::pushButton_RBODY_clicked);
            else if (pushButton->objectName() == "pushButton_SECTIO")
                connect(pushButton, &QPushButton::clicked, this, &GUIRadiossResultRequestDialog::pushButton_SECTIO_clicked);
        
        }
        _ui->treeWidget->setItemWidget(item, 1, widget);
        return item;
    }

    bool GUIRadiossResultRequestDialog::getCheckBoxState(const QString& objectName)
    {
        QCheckBox* checkBox = findChild<QCheckBox*>(objectName);
        return checkBox ? checkBox->isChecked() : false;
    }

    double GUIRadiossResultRequestDialog::getLineEditValue(const QString& objectName)
    {
        QLineEdit* lineEdit = findChild<QLineEdit*>(objectName);
        return lineEdit ? lineEdit->text().toDouble() : 0.0;
    }
}

